///********************************************************************
///* Copyright © 2011 fishr (fishr.flash@gmail.com)  
///********************************************************************
package su.fishr.effects.prismavision.elem 
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.events.Event;
	import flash.display.DisplayObject;
	import flash.geom.Point;
	import flash.geom.Rectangle;
	
	import su.fishr.geom.CheckAngle;
	
	
   /**
	 *  Модель вращающегося треугольника,
	 * сообщает состояние плоскостей в
	 * текущем состоянии поворота.
	 * @version                1.0
	 * @playerversion          Flash 9
	 * @langversion            3.0
	 * @author                 fishr
	 * @created                08.08.2011 19:28
	 * @since                  08.08.2011 19:28
	 */
	public  class ModelTriangle extends Sprite
	{
	
	/**-------------------------------------------------------------------------------
	* 
	*	   						V A R I A B L E ' S 	
	* 
	* --------------------------------------------------------------------------------
	*/
	//{
	    public static const AUTHOR:String = "fishr (fishr.flash@gmail.com)";	
		static public const ROTATION_END:String = "rotationEnd";
		 /**
		 *  Вращаемый контейнер  для опосредованного
		 * вращения объекта.
		 */
 
		private var _cntRotator:Sprite = new Sprite();	
		private var _point1:Sprite;
		private var _point2:Sprite;
		private var _point3:Sprite;
		private var _model:Sprite;
		private var _pnt:Point;
		private var _corr:Number = 7.5;
		private var _angleEnd:Number;
		private var _wTriangle:Number;
		private var _hTriangle:Number;
		private var _shadow:Shape;
		
		

	//}
	
	/**-------------------------------------------------------------------------------
	* 
	*	 						P R O P E R T I E S 	
	* 
	* --------------------------------------------------------------------------------
	*/
	//{
		public function set angleEnd(value:Number):void 
		{
			_angleEnd = value;
		}
		
	//}
	/**-------------------------------------------------------------------------------
	* 
	*								P U B L I C 	
	* 
	* --------------------------------------------------------------------------------
	*/
	//{
		public function ModelTriangle()
		{
			init();
		}
		
		public function rotateModel( angle:Number ):Array
		{
			
			if ( angle < 0 && _model.rotation <= _angleEnd + .001 || angle > 0 &&  _model.rotation >= _angleEnd - .001)
			{
				
				angle = _angleEnd - _model.rotation;
			}

			rotationContainer( _model, _pnt.x, _pnt.y, angle );

			var first:Rectangle = _point1.getRect(this);
			var second:Rectangle = _point2.getRect(this);
			var third:Rectangle = _point3.getRect(this);
			
			
			
			
			var xOut:Number =  ( first.x - _corr ) / 100 ;
			var scaleOut:Number = ( third.x - first.x) / 100;
			
			var xCom:Number = angle < 0? ( second.x - _corr ) / 100 : ( third.x - _corr ) / 100;
			var scaleCom:Number = angle < 0? ( first.x - second.x ) / 100 : (second.x - third.x ) / 100;

			var yOut:Number = first.y;

			var params:Array = [xOut, scaleOut, xCom, scaleCom];
			
			if ( _model.rotation === _angleEnd )
			{
				var ret:Number = _model.rotation > 0? - 120: 120;
				dispatchEvent( new Event (ROTATION_END));
				rotationContainer( _model, _pnt.x, _pnt.y, ret );
			}
			
			return params;
			
		}
		

	//}
	
	/**-------------------------------------------------------------------------------
	* 
	*								P R I V A T E 	
	* 
	* --------------------------------------------------------------------------------
	*/	
	//{
		
		private function init():void
		{
			
			var shape:Shape = createCarcase( 116, 116 );
			this.addChild( shape );
			
			var circ:Shape = createCircle();
			
			_wTriangle = 100;
			_hTriangle = 87.4;
			
			_model = createModel();
			_model.x = ( this.width - _model.width ) / 2;
			_model.y = ( ( this.height - _model.height ) / 2) - 14;
			
			circ.x = this.width / 2;
			circ.y = this.height / 2;
			this.addChild( circ );
			this.addChild( _model );
			
			

			_pnt = _model.globalToLocal( new Point( circ.x, circ.y ) );
						
		}
		

		
		private function createModel():Sprite
		{
			var spr:Sprite = new Sprite();
			var triangle:Shape = createTriangle(_wTriangle, _hTriangle, 0xFF0000);
			var carcase:Shape; 
			_point1 = new Sprite();
			_point2 = new Sprite();
			_point3 = new Sprite();
			
			carcase = createCarcase( 1, 1);
			_point1.addChild( carcase );
			carcase = createCarcase( 1, 1);
			_point2.addChild( carcase );
			carcase = createCarcase( 1, 1);
			_point3.addChild( carcase );
			
			spr.addChild( triangle );
			
			spr.addChild( _point1 );
			_point1.y = spr.height;
			spr.addChild( _point2 );
			_point2.x = spr.width / 2;
			spr.addChild( _point3 );
			_point3.y = spr.height -1;
			_point3.x = spr.width -1 ;
			
			
			return spr;
		}
		
		
		private function createTriangle(w:Number, h:Number, color:uint, shift:Number = .5):Shape
		{
			var shp:Shape = new Shape();
			shp.graphics.beginFill( color, 1 );
			shp.graphics.lineStyle( 0, 0x00FF00, 0 );
			shp.graphics.moveTo( 0, h );
			shp.graphics.lineTo( w, h );
			shp.graphics.lineTo( w * shift, 0);
			shp.graphics.lineTo( 0, h);
			shp.graphics.endFill();
			return shp;
		}
		
		
		private function createCircle():Shape
		{
			var shp:Shape = new Shape();
			shp.graphics.beginFill( 0x000000, 1 );
			shp.graphics.drawCircle( 0, 0, 58 );
			shp.graphics.endFill();
			return shp;
		}
		
		///удерживаем первоначальную форму модуля.
		private function createCarcase(w:Number, h:Number):Shape
		{
			var shape:Shape = new Shape();
			shape.graphics.lineStyle( 0, 0x00FF00, 1 );
			shape.graphics.lineTo(w, 0);
			shape.graphics.moveTo(w, 0);
			shape.graphics.lineTo(w, h);
			shape.graphics.moveTo( w, h);
			shape.graphics.lineTo( 0, h);
			shape.graphics.moveTo( 0, h);
			shape.graphics.lineTo(0, 0);
			shape.graphics.endFill();
			return shape;
		}
		
		

		/**
		 *  Вращает объект посредством вращения контейнера его содержащего
		 * и специально для этого созданного.
		 * 
		 * @param	obj - вращаемый вокруг произвольной точки объект
		 * @param	cX - координата точки по оси Х
		 * @param	cY - координата точки по оси У
		 * @param	angle - угол поворота в градусах.
		 */
		public function rotationContainer(obj:DisplayObject, cX:Number, cY:Number, angle:Number):void
		{
			var pGlobal:Point;
			var pRotate:Point;
			var pLocal:Point;
 
 
 
			/**
			 * Добавляем на сцену спрайт для поворота объекта,
			 * помещаем в него объект, сдвигаем спрайт относительно
			 * контейнера, а объект относительно нулевых координат 
			 * спрайта.
			 */
 
			if (_cntRotator.numChildren === 0) 
			{
				pGlobal = obj.localToGlobal(new Point(cX, cY));
				pRotate = obj.parent.globalToLocal(pGlobal);
			    obj.parent.addChild(_cntRotator);
				_cntRotator.addChild(obj);
				_cntRotator.x = pRotate.x; _cntRotator.y = pRotate.y;
				obj.x = -cX; obj.y = -cY;
			}
 
			/**
			 * вращаем (angle - градус поворота)
			 * это единственный способ поворота при котором возможно использование
			 * нативного твина,а это место где его, как раз, можно разместить
			 */
			_cntRotator.rotation += angle;
 
			/**
			 *  Удаляем отработавший спрайт, объект размещаем
			 * в первоначальном контейнере, предварительно преобразовав
			 * координаты объекта относительно спрайта для поворота, в координаты
			 * объекта первоначального контейнера, сдвигаем и поворачиваем
			 * его таким образом как был повернут спрайт
			 */
 
			pGlobal = obj.localToGlobal(new Point(0, 0));
			pLocal = _cntRotator.parent.globalToLocal(pGlobal);
 
			_cntRotator.removeChild(obj);
			_cntRotator.parent.addChild(obj);
			obj.parent.removeChild(_cntRotator);
			obj.rotation = _cntRotator.rotation;
			obj.x = pLocal.x;
			obj.y = pLocal.y;
 
 
			return;
 
		}

	//}

	}

}